(display "\n========================================\n")
(define (accmulate op initial seq)
    (if (null? seq)
        initial
        (op (car seq)
            (accmulate op initial (cdr seq)))))

(define (enumerate-interval low high)
    (if (> low high)
        ()
        (cons low (enumerate-interval (+ low 1) high))))

; (display (enumerate-interval 1 5))
; (newline)

(define (flatmap proc seq)
    (accmulate append () (map proc seq)))

(define (unique-pairs n)
    (flatmap (lambda (i)
                     (map (lambda (j) (list i j))
                          (enumerate-interval 1 (- i 1))))
             (enumerate-interval 1 n)))
(define up (unique-pairs 6))
(display up)
(newline)

(define (prime-sum? pair)
    (define (prime? x)
        (define (iter i)
            (cond ((> (* i i) x) #t)
                  ((= (remainder x i) 0) #f)
                  (else (iter (+ i 1)))))
        (iter 2))
    (prime? (+ (car pair) (cadr pair))))
; (display (prime-sum? (list 3 2)))
; (newline)

(define (get-prime-sum-pairs up)
    (filter prime-sum? up))

(display (get-prime-sum-pairs up))
(newline)

(define (prime-sum-pairs up)
    (map (lambda (upi) (append upi (list (+ (car upi) (cadr upi)))))
         (get-prime-sum-pairs up)))

(display (prime-sum-pairs up))
(newline)

(define (prime-sum-pairs n)
    (define (prime-sum? pair)
        (define (prime? x)
            (define (iter i)
                (cond ((> (* i i) x) #t)
                      ((= (remainder x i) 0) #f)
                      (else (iter (+ i 1)))))
            (iter 2))
        (prime? (+ (car pair) (cadr pair))))
    (let ((up (unique-pairs n)))
        (map (lambda (upi)
                     (append upi (list (+ (car upi) (cadr upi)))))
             (filter prime-sum? up))))

(display (prime-sum-pairs 6))
(newline)

(display "\n========================================\n")
